package org.ChrisRiffleSoftware.WhatIfJesusIsGod.ChuckNorrisJoker;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Random;

import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.View;
import android.view.View.OnClickListener;

/**
 * Note this class extends the {@link Activity} class, which is the primary class that all 
 * Android apps must extend(kind of like the class containing a 'main()' method in 
 * a regular simple java program.  This class can be considered kind of like the Android 
 * application's "entry point"
 * 
 * Since this is a simple/small app, it was decided to make this activity class go ahead and 
 * implement the {@link OnClickListener} and {@link OnInitListener}(for txt2Spch) interfaces 
 * to handle the appropriate processing. 
 * 
 * @author RIF
 */
public class ChuckNorrisJokerActivity extends Activity implements OnClickListener, OnInitListener{

	
	//*************************************************************
	//*************************************************************
	//				members
	//*************************************************************
	//*************************************************************
	
	/**
	 * Controller object that is used to control and coordinate how the 
	 * visual part of the application looks.  Passes data to/from the view's   
	 * screen components/widgets
	 */
	private ChuckViewController chuckViewController;
	
	/**
	 * The original 'first' list, containing all the jokes when the application is 
	 * first started.  As the user reads jokes, the jokes are randomly pulled/removed from 
	 * this "1st original list" variable, and they are inserted into a different list member 
	 * variable from this class "list 2".  
	 * 
	 * When all the jokes from 'list 1' are "used up"
	 * (removed and put into list2), the app will begin pulling jokes from list2 and putting 
	 * them back into list1.  With this approach, it aids in avoiding giving the user 
	 * duplicate jokes until all the jokes have been heard once. 
	 */
	private List<String> jokeList1;
	
	
	/**
	 * See comment for the 'joke list 1' variable
	 */
	private List<String> jokeList2;
	
	
	/**
	 * Flag signifying if jokes should currently be pulled/displayed from 
	 * list 1(if false - then list2 should be used)
	 * 
	 * TODO FIXME for Megan: change it to an enum w/2 values, one for each type of list,
	 *  instead of a boolean so we can take advantage of good design principles by using an 
	 *  enum.  This will be great for the future in case there are tons of different lists,
	 *  which could be used for different categories of jokes.
	 */
	private boolean bUseList1 = true;
	
	/**
	 * Used to get a random list index(joke position) from a list 
	 */
	private Random randomGenerator = new Random();
	
	/**
	 * Android library that gives us the ability to make the speaker orally/audibly 
	 * read text from a java string, intended only for english
	 */
	private TextToSpeech txtToSpeech;

	
	/**
	 * boolean flag used when calling the android library to make sure the user's 
	 * phone supports the english language
	 */
	private boolean phoneHasEnglish = false;
	
	
	//*************************************************************
	//*************************************************************
	//				overrides
	//*************************************************************
	//*************************************************************
	
	/**
	 * This is very similar to the "main()" method in a java program.
	 * (Android apps don't have a main method like regular java programs
	 * 
	 * This onCreate method is called when the Android application is first created.
	 * It's intended to setup/create the application,.. and then just wait for 
	 * the user to do something after which it will then respond appropriately
	 * 
	 * @param savedInstanceState
	 * 		In case our app was loading a saved state from disk,.. it would help 
	 * 		with restoring settings(such as tracking previously-viewed jokes
	 * 		ChuckNorrisJoker doesn't currently save anything though, so this 
	 * 		isn't really used 
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	
		/*
		 * Just call the super parent constructor in case it does something 
		 * fancy that helps us out
		 */
		super.onCreate(savedInstanceState);
	
		txtToSpeech = new TextToSpeech(this, this);
		
		/*
		 * Set the contents of this application's view("set the screen")  
		 * with a screen that we'll "get"/(create) with our "view controller" 
		 * class
		 */
		setContentView(getChuckViewController().getViewLayout());
		
		/*
		 * Programaticaly select our own "sound check box" so that the sound
		 * will be enabled by default
		 */
		getChuckViewController().getSoundToggleCheckBox().setChecked(true);
	}


	
	/**
	 * Handle processing -- a user just clicked on something  
	 * 
	 * TODO FIXME for Megan: 
	 * Instead of us just assuming that the click happened 
	 * on the "get random joke button" (it's the only current button we have now currently), 
	 * It would be better to only perform the "get random joke" functionality if we knew that it 
	 * was definitely the "get random joke button" that was clicked.  This can be done by(I think) setting 
	 * some kind of option on the "get random joke button" like this probably:
	 * 
	 *  randomJokeButton.setActionCommandName("randomJokeButtonClickEvent")
	 *  
	 *  (or something to that effect),.. we'll have to look up the Android api docs to figure the 
	 *  correct syntax with method names
	 *  
	 *  Then, inside this onClick method we could write something like:
	 *  
	 *  String eventName = viewParameterBeingClicked.getActionCommandName();
	 *  
	 *  if("randomJokeButtonClickEvent".equals(eventName)){
	 *  	//handle our button click processing
	 *  }
	 * 
	 */
	@Override
	public void onClick(View pViewBeingClicked) {
		
		String jokeString = getRandomJokeString();
		
		//display the joke text string on the screen
		getChuckViewController().getJokeTxtView().setText(jokeString);
		
				
		if(phoneHasEnglish && soundBoxIsChecked() ){
		
			//audibly read the joke out the user's speaker
			txtToSpeech.speak(jokeString, TextToSpeech.QUEUE_FLUSH, null);
		}
		
	}

	
	/**
	 * Returns true if the user has the sound box checked
	 * 
	 * @return
	 * 		true if the user has the sound box checked
	 */
	private boolean soundBoxIsChecked(){
		
		return getChuckViewController().getSoundToggleCheckBox().isChecked();
	}


	/**
	 * Called to signal the completion of the TextToSpeech engine
	 * initialization.
	 * 
	 * @param status
	 *            signifies if txt2Spch init was a success
	 */
	@Override
	public void onInit(int status) {

		getChuckViewController().getSubmitButton().setText("Loading...");

		//disable button until we're done loading the txt2speech functionality
		getChuckViewController().getSubmitButton().setEnabled(false);

		if (status == TextToSpeech.SUCCESS) {

			int result = txtToSpeech.setLanguage(Locale.US);

			phoneHasEnglish = (result != TextToSpeech.LANG_MISSING_DATA 
					&& result != TextToSpeech.LANG_NOT_SUPPORTED);

		}

		// done initializing, so we can set and enable the button now
		getChuckViewController().getSubmitButton().setText("DANGER");

		getChuckViewController().getSubmitButton().setEnabled(true);
	}

	
	/**
	 * makes an internal copy of the orig list w/items loaded from the 
	 * array w/array xml file so the new copyArrayList will be mutable
	 * 
	 * @return
	 */
	private List<String> getJokeList1(){
		
		if(jokeList1 == null){			
			
			String[] jokeArrayFromDisk = getResources().getStringArray(R.array.jokes);	
			
			List<String> immutableList = Arrays.asList(jokeArrayFromDisk); 
			
			//a mutable one(important so we can later remove jokes once they've been 
			// displayed so the user won't get bored seeing the same dumb jokes 
			// repeated all the time
			jokeList1 = new ArrayList<String>(immutableList);
		}
		return jokeList1;
	}
	


	/**
	 * getJokeList2
	 * 
	 * @return
	 * 		JokeList2
	 */
	private List<String> getJokeList2(){
		
		if(jokeList2 == null){
			
			jokeList2 = new ArrayList<String>();
		}
		return jokeList2;
	}
	
		
	
	/**
	 * getRandomJokeString
	 * 
	 * @param pJokeList
	 * 
	 * @return 
	 * 		null if list is out of jokes.  Returns the removed random joke 
	 * 		if the lists had some jokes left
	 */
	private String getRandomJokeString(){				

		if(bUseList1 && getJokeList1().isEmpty()){
			
			//recurse to list 2(b/c list 1 is empty)
			bUseList1 = false;
			getRandomJokeString();
									
		}else if(!bUseList1 && getJokeList2().isEmpty()){
			
			//back to list1(b/c list2 is empty)
			bUseList1 = true;
			getRandomJokeString();
		}				
			
		String joke = null;
		
		if(bUseList1){			
			
			int randomIndex = randomGenerator.nextInt(getJokeList1().size());			
			joke = getJokeList1().remove(randomIndex);
			getJokeList2().add(joke);
			
		}else{			
			
			int randomIndex = randomGenerator.nextInt(getJokeList2().size());
			joke = getJokeList2().remove(randomIndex);
			getJokeList1().add(joke);
		}								
		return joke;
	}
	

	/**
	 * getChuckViewController
	 * 
	 * @return
	 * 		ChuckViewController
	 */
	private ChuckViewController getChuckViewController() {
		
		if (chuckViewController == null) {
			
			chuckViewController = new ChuckViewController(this);
		}
		return chuckViewController;
	}
	

}



